package com.jing.yuntuku.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jing.yuntuku.annotation.AuthCheck;
import com.jing.yuntuku.config.UserConstant;
import com.jing.yuntuku.exception.BusinessException;
import com.jing.yuntuku.exception.ErrorCode;
import com.jing.yuntuku.mapper.UserMapper;
import com.jing.yuntuku.model.bean.User;
import com.jing.yuntuku.model.dto.*;
import com.jing.yuntuku.model.vo.UserLoginVo;
import com.jing.yuntuku.model.vo.UserVO;
import com.jing.yuntuku.result.BaseResponse;
import com.jing.yuntuku.service.UserService;
import com.jing.yuntuku.utils.ResultUtils;
import com.jing.yuntuku.utils.ThrowUtils;
import com.jing.yuntuku.utils.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping(("/user"))
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;

    /**
     * 注册
     *
     * @param userRegisterDto
     * @return
     */

    @PostMapping("/register")
    public BaseResponse<Long> register(@RequestBody UserRegisterDto userRegisterDto) {
        ThrowUtils.throwIf(userRegisterDto == null, ErrorCode.PARAMS_ERROR);
        String username = userRegisterDto.getUserAccount();
        String password = userRegisterDto.getUserPassword();
        String confirmpassword = userRegisterDto.getConfirmpassword();
        return ResultUtils.success(userService.Register(username, password, confirmpassword));
    }

    /**
     * 登录
     *
     * @param userLoginDto
     * @param request
     * @return
     */
    @PostMapping("/login")
    public BaseResponse<UserLoginVo> login(@RequestBody UserLoginDto userLoginDto, HttpServletRequest request) {
        ThrowUtils.throwIf(userLoginDto == null, ErrorCode.PARAMS_ERROR);
        UserLoginVo login = userService.login(userLoginDto.getUserAccount(), userLoginDto.getUserPassword(), request);
        return ResultUtils.success(login);
    }

    /**
     * 注销
     *
     * @param request
     * @return
     */
    @DeleteMapping("/logout")
    public BaseResponse<Boolean> logout(HttpServletRequest request) {
        return ResultUtils.success(userService.userLogout(request));
    }

    /**
     * 获取用户信息
     *
     * @param request
     * @return
     */
    @GetMapping("/getuser")
    public BaseResponse<UserLoginVo> getUser(HttpServletRequest request) {
        User user = userService.getUserLoginVo(request);
        UserLoginVo userLoginVo = new UserLoginVo();
        BeanUtils.copyProperties(user, userLoginVo);
        return ResultUtils.success(userLoginVo);
    }

    /**
     * 添加用户（管理员）
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> add(@RequestBody UserAddDto userAddDto) {
        //判断请求参数是否为空
        ThrowUtils.throwIf(userAddDto.getUserAccount().isEmpty(), new BusinessException(ErrorCode.PARAMS_ERROR, "账号不可以为空"));
        ThrowUtils.throwIf(!Objects.equals(userAddDto.getUserRole(),
                        UserConstant.ADMIN_ROLE) && !Objects.equals(userAddDto.getUserRole(), UserConstant.DEFAULT_ROLE)
                , new BusinessException(ErrorCode.SYSTEM_ERROR, "权限格式错误"));
        ThrowUtils.throwIf(userAddDto.getUserAccount().length() <= 4, new BusinessException(ErrorCode.SYSTEM_ERROR, "账号过短"));

        User user = new User();
        //复制对象
        BeanUtils.copyProperties(userAddDto, user);

        final String INITIAL_PASSWORD = "123456789";
        user.setUserPassword(UserUtils.getEncryptPassword(INITIAL_PASSWORD));
        ThrowUtils.throwIf(userMapper.getUserByUserAccount(user.getUserAccount()) != null, new BusinessException(ErrorCode.SYSTEM_ERROR, "账号已经存在了"));
        boolean save = userService.save(user);
        ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR);
        return ResultUtils.success(save);
    }

    /**
     * 根据id获取用户信息（管理员）
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<User> getUserById(long id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        User user = userService.getById(id);
        ThrowUtils.throwIf(user == null, new BusinessException(ErrorCode.SYSTEM_ERROR, "没有该用户"));
        return ResultUtils.success(user);
    }

    /**
     * 根据 id 获取包装类
     */
    @GetMapping("/get/vo")
    public BaseResponse<UserVO> getUserVOById(long id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        BaseResponse<User> response = getUserById(id);
        User user = response.getData();
        return ResultUtils.success(userService.getUserVO(user));
    }

    /**
     * 删除用户
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteDto deleteDto) {
        ThrowUtils.throwIf(deleteDto == null || deleteDto.getId() <= 0, ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(userService.getById(deleteDto.getId()) == null, new BusinessException(ErrorCode.SYSTEM_ERROR, "账号不存在"));
        boolean b = userService.removeById(deleteDto.getId());
        ThrowUtils.throwIf(!b, new BusinessException(ErrorCode.SYSTEM_ERROR, "删除失败"));
        return ResultUtils.success(b);
    }

    /**
     * 更新用户
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateDto userUpdateDto) {
        ThrowUtils.throwIf(userUpdateDto == null, ErrorCode.PARAMS_ERROR);
        User user = new User();
        BeanUtils.copyProperties(userUpdateDto, user);
//        ThrowUtils.throwIf(userService.getUserVO(user)!=null, new BusinessException(ErrorCode.SYSTEM_ERROR,"账号已存在"));
        boolean b = userService.updateById(user);
        ThrowUtils.throwIf(!b, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(b);
    }

    /**
     * 分页获取用户封装列表（仅管理员可操作）
     *
     * @param userQueryDto 查询请求参数，包含分页及查询条件等信息
     * @return 包含用户视图对象分页结果的统一响应
     */
    @PostMapping("/list/page/vo")  // 标识该方法处理POST请求，请求路径为/list/page/vo
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)  // 权限校验，要求必须是管理员角色才能访问
    public BaseResponse<Page<UserVO>> listUserVOByPage(@RequestBody UserQueryDto userQueryDto) {
        // 校验请求参数，若为null则抛出参数错误异常
        ThrowUtils.throwIf(userQueryDto == null, ErrorCode.PARAMS_ERROR);
        // 从查询请求参数中获取当前页码
        long current = userQueryDto.getCurrent();
        // 从查询请求参数中获取每页显示条数
        long pageSize = userQueryDto.getPageSize();
        // 调用userService的page方法，基于MyBatis - Plus进行分页查询，传入分页条件和查询条件包装器
        Page<User> userPage = userService.page(new Page<>(current, pageSize),
                userService.getQueryWrapper(userQueryDto));
        // 构建用户视图对象的分页结果对象，设置当前页、每页大小、总记录数
        Page<UserVO> userVOPage = new Page<>(current, pageSize, userPage.getTotal());
        // 将查询得到的用户实体列表转换为用户视图对象列表
        List<UserVO> userVOList = userService.getUserVOList(userPage.getRecords());
        // 将转换后的用户视图对象列表设置到分页结果对象中
        userVOPage.setRecords(userVOList);
        // 封装并返回成功响应，包含用户视图对象的分页结果
        return ResultUtils.success(userVOPage);
    }
}
